﻿using System;
using System.Windows;
using DSLPedItemWizard.Messages;
using DSLPedItemWizard.Views;
using Dsl.Ped.Common;
using Dsl.Ped.Framework.AddIns;
using GalaSoft.MvvmLight.Command;
using System.Collections.Generic;

using GalaSoft.MvvmLight.Messaging;

namespace DSLPedItemWizard.ViewModels
{
    /// <summary>
    /// View model of a <see cref="MainWizardWindow"/>
    /// </summary>
    public class MainWizardWindowViewModel : ViewModelBase
    {
        #region Fields

        /// <summary>
        /// Command executed when the Next button is clicked
        /// </summary>
        private RelayCommand nextCommand;

        /// <summary>
        /// Command executed when the Previous button is clicked
        /// </summary>
        private RelayCommand previousCommand;

        /// <summary>
        /// Current index of the page
        /// </summary>
        private int currentIndex = 0;

        /// <summary>
        /// All available pages
        /// </summary>
        private List<IWizardPage> pages = null;

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="MainWizardWindowViewModel"/> class.
        /// </summary>
        /// <param name="pages">The pages wizard pages</param>
        /// <param name="messenger">The messenger for the communication among wizard pages</param>
        public MainWizardWindowViewModel(List<IWizardPage> pages, Messenger messenger)
        {
            this.pages = pages;
            this.currentIndex = 0;

            messenger.Register<CanFinishMessage>(this, OnCanFinishMessage);
        }

        /// <summary>
        /// Gets the content of the current page
        /// </summary>
        public FrameworkElement PageContent
        {
            get
            {
                return pages[currentIndex].View;
            }
        }

        /// <summary>
        /// Gets the command executed when the previous button is clicked
        /// </summary>
        public RelayCommand PreviousCommand
        {
            get
            {
                return previousCommand ?? (previousCommand = new RelayCommand(OnPreviousCommand));
            }
        }

        /// <summary>
        /// Get the command executed when the next button is clicked
        /// </summary>
        public RelayCommand NextCommand
        {
            get
            {
                return nextCommand ?? (nextCommand = new RelayCommand(OnNextCommand));
            }
        }

        /// <summary>
        /// Gets the value indicating that the finish button is enabled
        /// </summary>
        public bool IsFinishEnabled
        {
            get
            {
                var lastPage = currentIndex == pages.Count - 1;
                var canFinish = pages[currentIndex].CanFinish;

                return lastPage && canFinish;
            }
        }

        /// <summary>
        /// Gets the indication whether the previous button is visible
        /// </summary>
        public bool IsPreviousVisible
        {
            get
            {
                return currentIndex != 0;
            }
        }

        /// <summary>
        /// Gets the indication whether the next button is visible
        /// </summary>
        public bool IsNextVisible
        {
            get
            {
                return currentIndex != pages.Count - 1;
            }
        }

        /// <summary>
        /// Gets the currently selected AddIn
        /// </summary>
        public Lazy<IDslPedAddIn, IDslPedAddInMetadata> SelectedAddIn
        {
            get
            {
                if (pages[pages.Count - 1] is SelectionWizardView)
                {
                    SelectionWizardView selectionWizardView = pages[pages.Count - 1] as SelectionWizardView;
                    return selectionWizardView.SelectedAddIn;
                }
                else
                {
                    return null;
                }
            }
        }

        /// <summary>
        /// Handler method executed when the Previous command is executed
        /// </summary>
        private void OnPreviousCommand()
        {
            currentIndex--;
            RaisePropertyChanged(() => PageContent);
            RaisePropertyChanged(() => IsPreviousVisible);
            RaisePropertyChanged(() => IsNextVisible);
            RaisePropertyChanged(() => this.IsFinishEnabled);
        }

        /// <summary>
        /// Handler method executed when the Next command is executed
        /// </summary>
        private void OnNextCommand()
        {
            currentIndex++;
            RaisePropertyChanged(() => PageContent);
            RaisePropertyChanged(() => IsPreviousVisible);
            RaisePropertyChanged(() => IsNextVisible);
            RaisePropertyChanged(() => this.IsFinishEnabled);
        }

        /// <summary>
        /// Handler method that enables a finish button when the <see cref="CanFinishMessage"/>
        /// is received
        /// </summary>
        /// <param name="canFinishMessage">Instance of the <see cref="CanFinishMessage"/></param>
        private void OnCanFinishMessage(CanFinishMessage canFinishMessage)
        {
            RaisePropertyChanged(() => IsFinishEnabled);
        }
    }
}
